package com.linktco.common.utils;


import lombok.Data;
import lombok.SneakyThrows;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;

/**
 * @author yuguang
 * @date 2021/5/17 17:33
 * @description 获取地址： http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/
 * 省：两位数字
 * 市：四位数字
 * 区县：六位数字
 */
public class AreaSync {
    public static final String BASE_URL = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021";
    private static final int TIMEOUT = 1000*10;
    private static Document document;
    public static Connection con;

    private static Map<Integer, String> classMap = new HashMap<Integer, String>();
    static {
        classMap.put(1, "provincetr");
        classMap.put(2, "citytr");
        classMap.put(3, "countytr");
        classMap.put(4, "towntr");
        classMap.put(5, "villagetr");
    }


    @SneakyThrows
    public static void main(String[] args) {
        getCon();

        List<SysArea> provinceList = getProvinceList(BASE_URL);
        for (SysArea province : provinceList) {
            outputPrint(province.getLevel(), province.getAreaCode(), province.getAreaName());

            List<SysArea> cityList = getAreaList(province.getUrlPath(), province.getParentPath(), province.getLevel() + 1, province.getAreaCode());
            for (SysArea city : cityList) {
                outputPrint(city.getLevel(), city.getAreaCode(), city.getAreaName());

                List<SysArea> countyList = getAreaList(city.getUrlPath(), city.getParentPath(), city.getLevel() + 1, city.getAreaCode());
                for (SysArea county : countyList) {
                    outputPrint(county.getLevel(), county.getAreaCode(), county.getAreaName());

                    List<SysArea> townList = getAreaList(county.getUrlPath(), county.getParentPath(), county.getLevel() + 1, county.getAreaCode());
                    for (SysArea town : townList) {
                        outputPrint(town.getLevel(), town.getAreaCode(), town.getAreaName());

                        List<SysArea> villageList = getAreaList(town.getUrlPath(), town.getParentPath(), town.getLevel() + 1, town.getAreaCode());
                        for (SysArea village : villageList) {
                            outputPrint(village.getLevel(), village.getAreaCode(), village.getAreaName());
                        }
                    }
                }
            }
        }
    }


    @SneakyThrows
    public static Connection getCon(){
        Class.forName("com.mysql.cj.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://10.10.5.101:3306/common_admin?useSSL=TRUE&serverTimezone=UTC","root","1655658911");
        return con;
    }




    /**
     * 获取省
     *
     * @param provinceUrl
     * @return
     * @throws IOException
     */
    public static List<SysArea> getProvinceList(String provinceUrl) {
        List<SysArea> areaList = new ArrayList<>();
        getDocument(provinceUrl);
        //获取省份列表
        ListIterator<Element> elementList = document.getElementsByClass(classMap.get(1)).listIterator();

        while (elementList.hasNext()) {
            ListIterator<Element> tds = elementList.next().children().listIterator();
            while (tds.hasNext()) {
                Element element = tds.next().child(0);
                String href = element.attr("href");
                String areaCode = href.substring(0, href.indexOf(".html"));
                String areaUrl = BASE_URL + "/" + href;
                addAreaList(areaList, areaCode, element.text(), areaUrl, areaCode, 1, "0");
            }
        }
        return areaList;
    }





    /**
     * @param cityUrl
     * @param level
     * @param parentCode
     * @return
     */
    public static List<SysArea> getAreaList(String cityUrl, String parentPath, Integer level, String parentCode) throws InterruptedException {

        List<SysArea> areaList = new ArrayList<>();
        getDocument(cityUrl);
        Elements elementList = document.getElementsByClass(classMap.get(level));

        for (Element element : elementList) {
            String code, name;

            Elements elements = element.getElementsByTag("a");
            if (level == 5) {
                elements = element.getElementsByTag("td");
                if (elements.isEmpty()) {
                    continue;
                }
                code = elements.get(0).text();
                name = elements.get(2).text();
            } else {
                if (elements.isEmpty()) {
                    continue;
                }
                code = elements.get(0).text();
                name = elements.get(1).text();
            }

            String href = elements.get(0).attr("href");
            String pPath = parentPath;
            if (level >= 3) {
                pPath = parentPath + "/" + href.split("/")[0];
                href = parentPath + "/" + href;
            }

            cityUrl = BASE_URL + "/" + href;
            addAreaList(areaList, code, name, cityUrl, pPath, level, parentCode);
        }
        return areaList;
    }


    private static void outputPrint(Integer level, String areaCode, String areaName) {
        String str = "";
        for (int i = 0; i <= (level - 1) * 2; i++) {
            str += " ";
        }

        String format = String.format("%s%s级——>%s——>%s", str, level, areaCode, areaName);
        System.out.println(format);

    }


    private static void getDocument(String url) {
        if (U.isEmpty(url)) {
            throw new IllegalArgumentException("传入的这个url('" + url + "') 是无效的!");
        }
        try {
            Thread.sleep(100);
            document = Jsoup.connect(url).timeout(TIMEOUT).get();
        } catch (Exception e) {
            e.printStackTrace();
            getDocument(url);
        }
    }


    private static void addAreaList(List<SysArea> areaList, String areaCode, String areaName, String href, String parentPath, Integer level, String parentCode) {
        SysArea sysArea = new SysArea();
        sysArea.setAreaCode(areaCode);
        sysArea.setAreaName(areaName);
        sysArea.setLevel(level);
        sysArea.setParentCode(parentCode);
        sysArea.setUrlPath(href);
        sysArea.setParentPath(parentPath);
        insert(sysArea);
        areaList.add(sysArea);
    }

    /**
     * 将数据插入数据库
     * @param sysArea
     * @throws SQLException
     */
    @SneakyThrows
    public static void insert(SysArea sysArea) {
        String sql = "insert into sys_area(area_code,area_name,level,parent_code) values(?,?,?,?)";
        PreparedStatement p = con.prepareStatement(sql);
        p.setString(1,sysArea.getAreaCode());
        p.setString(2,sysArea.getAreaName());
        p.setString(3,sysArea.getLevel().toString());
        p.setString(4,sysArea.getParentCode());
        p.executeUpdate();
        p.close();
    }

    @Data
    static class SysArea {
        private String areaCode;
        private String areaName;
        private String parentCode;
        private Integer level;
        private String urlPath;
        private String parentPath;
    }

    /**
     * CREATE TABLE `sys_area` (
     *   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
     *   `area_code` varchar(50) DEFAULT NULL COMMENT '区域编码',
     *   `area_name` varchar(50) DEFAULT NULL COMMENT '区域名称',
     *   `level` int(2) DEFAULT NULL COMMENT '级别',
     *   `parent_code` varchar(50) DEFAULT NULL COMMENT '父区域编码',
     *   PRIMARY KEY (`id`)
     * ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     */

}
